using System.Diagnostics;
using System.Runtime.CompilerServices;

namespace BepuPhysics.Collidables
{
    public struct TypedIndex
    {
        /// <summary>
        /// 类型化索引的位压缩表示形式。
        /// </summary>
        public uint Packed;

        /// <summary>
        /// 获取该对象的类型索引。
        /// </summary>
        public int Type
        {
            [MethodImpl(MethodImplOptions.AggressiveInlining)]
            get { return (int)(Packed & 0x7F000000) >> 24; }
        }

        /// <summary>
        /// 获取该对象的索引。
        /// </summary>
        public int Index
        {
            [MethodImpl(MethodImplOptions.AggressiveInlining)]
            get { return (int)(Packed & 0x00FFFFFF); }
        }

        /// <summary>
        /// 获取此索引是否实际引用任何内容。仅当为真时才应使用Type和Index。
        /// </summary>
        public bool Exists
        {
            [MethodImpl(MethodImplOptions.AggressiveInlining)]
            get { return (Packed & (1 << 31)) > 0; }
        }

        public TypedIndex(int type, int index)
        {
            Debug.Assert(type >= 0 && type < 128, "Do you really have that many type indices, or is the index corrupt?");
            Debug.Assert(index >= 0 && index < (1 << 24), "Do you really have that many instances, or is the index corrupt?");
            // 请注意,在最高有效时隙中包含一个设置位。
            // 这表明索引是显式构造的,因此它是一个"真实"引用。
            // 默认构造的TypeIndex在MSB中将具有0,因此我们可以对空引用使用默认构造函数。
            Packed = (uint)((type << 24) | index | (1u << 31));
        }

        public override string ToString()
        {
            return $"<{Type}, {Index}>";
        }

    }
}
